package thread.timethreadpool;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.*;

/**
 * @auther zhouliangliang
 * @date 2022/7/25 9:54
 * @description 自定义Timer线程池，用来记录线程的执行时间
 */
public class TimerThreadPoolExecutor extends ThreadPoolExecutor {

	private Logger logger = LoggerFactory.getLogger(TimerThreadPoolExecutor.class);

	private ThreadLocal<Long> threadLocal = new ThreadLocal<>();

	public TimerThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
								   TimeUnit unit, BlockingQueue<Runnable> workQueue) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
	}

	public TimerThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
								   TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory factory) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, factory);
	}

	public TimerThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
								   TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory factory, RejectedExecutionHandler handler) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, factory, handler);
	}



	@Override
	protected void beforeExecute(Thread t, Runnable r) {
		try{
			long startTime = System.currentTimeMillis();
			threadLocal.set(startTime);
		} catch (Exception e) {
			logger.error("GatewayThreadPool.beforeExecute error " + e.getMessage(), e);
		} finally {
			super.beforeExecute(t, r);
		}
	}

	@Override
	protected void afterExecute(Runnable r, Throwable t) {
		try {
			long endTime = System.currentTimeMillis();
			long startTime = threadLocal.get();
			long duration = endTime - startTime;
			System.out.println(Thread.currentThread().getName() + " cost " + duration + " ms");
//			logger.info(Thread.currentThread().getName() + " cost " + duration + " ms");
		} catch (Exception e) {
			logger.error("GatewayThreadPool.afterExecute error " + e.getMessage(), e);
		} finally {
			super.afterExecute(r, t);
		}
	}
}
